import {Muster, RemoveKeys} from "@/types/utils";

// 截取后缀名
export function getSuffix(value: string) {
    let newValue
    if (value && value.lastIndexOf('.') != -1) {
        newValue = value.slice(value.lastIndexOf('.'))
    } else {
        console.error('请传入正确的格式!');
        return
    }
    return newValue
}

// 获取集合并返回字符串
export const getMusterProps = (classMusters?: string | number | object | Muster[]) => {
    if (!classMusters) return "";
    let classList: string[] = analyzeMusterProps(classMusters);
    return classList.join(" ");
}
// 解析集合 返回 数组
const analyzeMusterProps = (classMusters: string | number | object | Muster[]) => {
    let classList: string[] = [];
    if (typeof classMusters == "string" || typeof classMusters == "number") {
        classList.push(String(classMusters))
    } else if (Array.isArray(classMusters)) {
        classMusters.forEach(item => {
            classList.push(...analyzeMusterProps(item))
        });
    } else {
        Object.entries(classMusters).forEach(([key, value]) => {
            if (!!value) classList.push(key);
        })
    }
    return classList;
}

// 切割地址栏url?后面的参数
export const getUrlParams = (
    url: string,
    equal: string = "=",
    and: string = "&",
    question: string = "?"
) => {
    let parameters = url.indexOf(question) != -1 ? url.split(question)[1] : url;
    let strs = parameters.split(and);
    let obj: Muster = {};
    strs.forEach((item) => {
        obj[item.split(equal)[0]] = item.split(equal)[1];
    });
    return obj;
}

// 对象转str
export const obj2str = <Params extends Object>(obj: Params, separator: string = "&") => {
    if (Object.keys(obj).length) {
        let str = "";
        for (let [key, value] of Object.entries(obj)) {
            str += `${key}=${value}${separator}`;
        }
        str = "?" + str.substring(0, str.length - 1);
        return str;
    }
    return "";
}

// 等块分割数组或字符串
export const blockSlice = <V>(value: V[] | string, block: number = 2) => {
    let list: Array<V[] | string> = [];
    for (let index = 0; index < value.length; index++) {
        if (index % block == 0) {
            list.push(value.slice(index, index + block));
        }
    }
    return list;
}

// 数组对象去重
export const uniqBy = <T>(
    array: T[],
    iteratee: string | ((item: T) => string | number)
): T[] => {
    let iterators: (item: T) => string | number;
    if (typeof iteratee === "string") {
        iterators = (item) => (item as any)[iteratee];
    } else {
        iterators = iteratee;
    }
    const filterAfterArr = Array.from(new Set(array.map(iterators)));
    const newArr = filterAfterArr.map(val =>
        array.find(item => iterators(item) === val)
    );
    return newArr as T[]
}

// 深合并对象
export function deepMerge(target: object, source: any): any {
    const output: any = {...target};
    if (isObject(source)) {
        for (const key in source) {
            if (isObject(source[key])) {
                if (!(key in output)) {
                    output[key] = {} as any;
                }
                output[key] = deepMerge(output[key], source[key]);
            } else {
                output[key] = source[key];
            }
        }
    }
    return output;
}

// 是否是对象
export function isObject<O>(obj?: O): boolean {
    if (!obj) return false;
    return Object.keys(obj).length > 0 && typeof obj === 'object';
}

// 深拷贝
export function deepClone<T extends Muster>(obj: T) {
    if (obj === null || typeof obj !== "object") {
        return obj;
    }
    let clone: Muster ;
    if (obj instanceof Date) {
      clone = new Date(obj.getTime()) as any;
    } else if (Array.isArray(obj)) {
      clone = [] as any;
    } else {
      clone = {} as any;
    }
    Object.keys(obj).forEach((key: string | number) => {
        clone[key] = deepClone(obj[key]);
    });
    return clone as T;
}


export function deObjectKey<T extends Muster,K extends keyof T>(
    obj: T,
    keys: K[] | K,
    invert?: boolean
): RemoveKeys<T, K> {
    const result: any = {};
    const keysToRemove = (typeof keys == "string" ? keys.split(',') : keys) as K[];

    Object.keys(obj).forEach((key) => {
        let bol = keysToRemove.includes(key as K);
        if (invert ? !bol : bol) {
            result[key] = obj[key];
        }
    });

    return result as RemoveKeys<T, K>;
}

// 更新对象属性
export function updateObjProps(obj: Muster, name: string, value: any) {
  if (!name) obj = value;
  const keys = name.split(".");
  if (keys.length < 2) {
    obj[name] = value;
    return obj;
  }
  let target = obj as any;
  for (let i = 0; i < keys.length - 1; i++) {
    if (target.hasOwnProperty(keys[i])) {
      target = target[keys[i]];
    } else {
      target[keys[i]] = {};
    }
  }
  target[keys[keys.length - 1]] = value;
  return obj;
}

// 获取对象深层属性
export function getObjDeepProps(obj: Muster, name: string): any {
    const keys = name.split('.');
    let target: any = obj;
    for (let i = 0; i < keys.length; i++) {
        // target = target[keys[i]];
        if (target.hasOwnProperty(keys[i])) {
            target = target[keys[i]];
        } else {
            target[keys[i]] = {};
        }
    }
    return target;
}


// 转换key
export function convert<T, R>(obj: T) {
    if (typeof obj !== 'object') return obj;
    let newObj: any = {};
    for (let key in obj) {
        if (typeof obj[key] === 'object') {
            newObj[key] = convert(obj[key]); // 递归转换值
        } else {
            newObj[key] = `var(--ant-${convertKey(key)})`;
        }
    }
    return newObj;
}

// 将键名转换为CSS变量格式
export function convertKey(key: string) {
    return key.replace(/([A-Z])/g, '-$1').toLowerCase();
}

// 数组对象转换为二维数组  可互转
export function convertArrayObjects(arrObj: any[], maps: string[]): any {
    let newArr: any = [];
    arrObj.forEach((item, index) => {
        if (Array.isArray(item)) {
            let obj: any = {};
            item.forEach((itm, idx) => {
                obj[maps[idx]] = itm
            });
            newArr.push(obj);
        } else {
            newArr.push(Object.values(item));
        }
    })
    return newArr;
}

// 提取固定字符
export function extractString(str: string, regex: RegExp) {
    const match = str.match(regex);
    return match ? match[0] : '';
}

// 将第一个字符转为小写
export function strFirstLetter(str: string) {
    return str.replace(/\b[a-z]/, function (char) {
        return char.toUpperCase();
    });
}

// 对象扁平化
export const objFlat = (obj: object) => {
    let newObj:Muster = {};
    const recursion = (o: Muster) => {
        Object.keys(o).forEach(key => {
            const value = o[key];
            if (Object.keys(value).length) {
                recursion(value)
            } else {
                newObj[key] = value;
            }
        });
    }
    recursion(obj);
    return newObj;
}